home *** CD-ROM | disk | FTP | other *** search
- #define LIBQDISPLAY_CORE
- #include "../include/libqdisplay.h"
-
- /*
- * CLIPPOLY.c - LOTS OF WORK TO DO :)
- */
-
- static point_3d clipPoints[16], *clipList1[40], *clipList2[40];
-
- #define X p[0]
- #define Y p[1]
- #define Z p[2]
-
- static void intersect(point_3d * out, point_3d * a, point_3d * b, float where)
- {
- // intersection occurs 'where' % along the line from a to b
- out->X = a->X + (b->X - a->X) * where;
- out->Y = a->Y + (b->Y - a->Y) * where;
- out->Z = a->Z + (b->Z - a->Z) * where;
-
- transform_rotated_point(out);
- }
-
- // compute 'where' for various clip planes
- static float left_loc(point_3d * a, point_3d * b)
- {
- return -(a->Z + a->X * clipScaleX) / ((b->X - a->X) * clipScaleX + b->Z - a->Z);
- }
-
- static float right_loc(point_3d * a, point_3d * b)
- {
- return (a->Z - a->X * clipScaleX) / ((b->X - a->X) * clipScaleX - b->Z + a->Z);
- }
-
- static float top_loc(point_3d * a, point_3d * b)
- {
- return (a->Z - a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY - b->Z + a->Z);
- }
-
- static float bottom_loc(point_3d * a, point_3d * b)
- {
- return -(a->Z + a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY + b->Z - a->Z);
- }
-
- // clip the polygon to each of the view frustrum planes
- int clip_poly(int n, point_3d ** vl, int codes_or, point_3d *** out_vl)
- {
- int i, j, k, p = 0; // p = index into temporary point pool
-
- point_3d **cur;
-
- if (codes_or & CC_OFF_LEFT) {
- cur = clipList1;
- k = 0;
- j = n - 1;
- for (i = 0; i < n; ++i) {
- // process edge from j..i
- // if j is inside, add it
- if (!(vl[j]->ccodes & CC_OFF_LEFT))
- cur[k++] = vl[j];
- // if it crosses, add the intersection point
- if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_LEFT) {
- intersect(&clipPoints[p], vl[i], vl[j], left_loc(vl[i], vl[j]));
- cur[k++] = &clipPoints[p++];
- }
- j = i;
- }
- // move output list to be input
- n = k;
- vl = cur;
- }
-
- if (codes_or & CC_OFF_RIGHT) {
- cur = (vl == clipList1) ? clipList2 : clipList1;
- k = 0;
- j = n - 1;
- for (i = 0; i < n; ++i) {
- if (!(vl[j]->ccodes & CC_OFF_RIGHT))
- cur[k++] = vl[j];
- if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_RIGHT) {
- intersect(&clipPoints[p], vl[i], vl[j], right_loc(vl[i], vl[j]));
- cur[k++] = &clipPoints[p++];
- }
- j = i;
- }
- n = k;
- vl = cur;
- }
- if (codes_or & CC_OFF_TOP) {
- cur = (vl == clipList1) ? clipList2 : clipList1;
- k = 0;
- j = n - 1;
- for (i = 0; i < n; ++i) {
- if (!(vl[j]->ccodes & CC_OFF_TOP))
- cur[k++] = vl[j];
- if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_TOP) {
- intersect(&clipPoints[p], vl[i], vl[j], top_loc(vl[i], vl[j]));
- cur[k++] = &clipPoints[p++];
- }
- j = i;
- }
- n = k;
- vl = cur;
- }
- if (codes_or & CC_OFF_BOT) {
- cur = (vl == clipList1) ? clipList2 : clipList1;
- k = 0;
- j = n - 1;
- for (i = 0; i < n; ++i) {
- if (!(vl[j]->ccodes & CC_OFF_BOT))
- cur[k++] = vl[j];
- if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_BOT) {
- intersect(&clipPoints[p], vl[i], vl[j], bottom_loc(vl[i], vl[j]));
- cur[k++] = &clipPoints[p++];
- }
- j = i;
- }
- n = k;
- vl = cur;
- }
-
- for (i = 0; i < n; ++i)
- if (vl[i]->ccodes & CC_BEHIND)
- return 0;
-
- *out_vl = vl;
- return n;
- }
-